﻿using System;
using System.Collections.Generic;
using System.Text;
using Barbar.UrlGuard.Dal;
using Barbar.UrlGuard.Dal.Persist;

namespace Barbar.UrlGuard.BL.Concrete {
  internal class DataContextUpdator : IDataContextUpdator {
    private IHistoryPersistor m_HistoryPersistor;
    private IDataContextHolder m_DataContextHolder;


    public DataContextUpdator(IHistoryPersistor historyPersisor, IDataContextHolder dataContextHolder) {
      if (historyPersisor == null)
        throw new ArgumentNullException("historyPersistor");

      if (dataContextHolder == null)
        throw new ArgumentNullException("dataContextHolder");

      m_HistoryPersistor = historyPersisor;
      m_DataContextHolder = dataContextHolder;
    }

    #region IDataContextUpdator Members

    public void UpdateContextWithCheck(IEnumerable<MonitoringEntry> checkedEntries, out bool isError, out bool isNewError) {
      if (checkedEntries == null)
        throw new ArgumentNullException("checkedEntries");

      bool currentNewError = false;

      foreach (MonitoringEntry checkEntry in checkedEntries) {
        bool isCurrentError, isCurrentNewError;
        UpdateEntry(checkEntry, out isCurrentError, out isCurrentNewError);
        currentNewError |= isCurrentNewError;
      }
      m_DataContextHolder.Persist();

      bool currentError = false;
      foreach (MonitoringEntry checkEntry in m_DataContextHolder.Context.Entries) {
        if (checkEntry.Status.Value == MonitoringEntryStatus.Error.Value) {
          currentError = true;
          break;
        }
      }

      isError = currentError;
      isNewError = currentNewError;
    }

    private void UpdateEntry(MonitoringEntry checkEntry, out bool isError, out bool isNewError) {
      if (checkEntry == null)
        throw new ArgumentNullException("checkEntry");

      isError = false;
      isNewError = false;

      MonitoringEntry boundEntry = m_DataContextHolder.Context.GetEntryByID(checkEntry.Uid);
      if (boundEntry == null)
        return;

      isError = checkEntry.Status == MonitoringEntryStatus.Error;
      if (isError) {
        isNewError = (boundEntry.Status.Value == MonitoringEntryStatus.OK.Value ||
          boundEntry.Status.Value == MonitoringEntryStatus.None.Value);
      }

      boundEntry.LastCheckDate = checkEntry.LastCheckDate;
      boundEntry.LastRequestLength = checkEntry.LastRequestLength;
      boundEntry.LastStatusCode = checkEntry.LastStatusCode;

      MonitoringCheck check = new MonitoringCheck();
      check.CheckDate = boundEntry.LastCheckDate.Value;
      check.RequestLength = boundEntry.LastRequestLength;
      check.StatusCode = boundEntry.LastStatusCode;

      m_HistoryPersistor.SaveCheck(boundEntry.Uid, check);
    }

    #endregion
  }
}
